import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;

public class Liste {

public HashMap<String,Integer> argFctPredefinie = new HashMap<String,Integer>();
	
	public HashMap<String,Method> methodFctPredefinie = new HashMap<String,Method>();
	
	public Liste() {
		argFctPredefinie.put("premier", 1);
		argFctPredefinie.put("dernier", 1);
		argFctPredefinie.put("saufpremier", 1);
		argFctPredefinie.put("saufdernier", 1);
		argFctPredefinie.put("item", 2);
		argFctPredefinie.put("liste", 2);
		argFctPredefinie.put("phrase", 2);
		argFctPredefinie.put("metspremier", 2);
		argFctPredefinie.put("metsdernier", 2);
		argFctPredefinie.put("inverse", 1);
		argFctPredefinie.put("compte", 1);
		
		Class c = Liste.class;
		Method[] tab = c.getMethods();
		
		Method  m;
		for (int i=0;i<tab.length;i++) {
			m = tab[i];
	
			if(m.getName().equals("premier"))
				methodFctPredefinie.put("premier", m);
			
			if(m.getName().equals("dernier"))
				methodFctPredefinie.put("dernier", m);
			
			if(m.getName().equals("saufpremier"))
				methodFctPredefinie.put("saufpremier", m);
	
			if(m.getName().equals("saufdernier"))
				methodFctPredefinie.put("saufdernier", m);
			
			if(m.getName().equals("item"))
				methodFctPredefinie.put("item", m);
			
			if(m.getName().equals("liste"))
				methodFctPredefinie.put("liste", m);
			
			if(m.getName().equals("phrase"))
				methodFctPredefinie.put("phrase", m);
			
			if(m.getName().equals("metspremier"))
				methodFctPredefinie.put("metspremier", m);

			if(m.getName().equals("metsdernier"))
				methodFctPredefinie.put("metsdernier", m);
			
			if(m.getName().equals("inverse"))
				methodFctPredefinie.put("inverse", m);
			
			if(m.getName().equals("compte"))
				methodFctPredefinie.put("compte", m);
		}    
	};
	
	public static Object premier(ArrayList<Object> v,  HashMap<String, Object> penv) {
		
		if(v.size()== 1)
			if(v.get(0) instanceof ArrayList)	
				return ((ArrayList)v.get(0)).get(0);
			else 
				if(v.get(0) instanceof String)	
					return ((String)v.get(0)).charAt(0);
				else return null;
		else return null;
	}
	
	
	public static Object dernier(ArrayList<Object> v,  HashMap<String, Object> penv) {
		
		if(v.size()== 1)
			if(v.get(0) instanceof ArrayList)	
				return ((ArrayList)v.get(0)).get(((ArrayList)v.get(0)).size()-1);
			else 
				if(v.get(0) instanceof String)	
					return ((String)v.get(0)).charAt(((String)v.get(0)).length()-1);
				else return null;
		else return null;
	}
	



	public static Object saufpremier(ArrayList<Object> v,  HashMap<String, Object> penv) {
	
		
	if(v.size()== 1)
		if(v.get(0) instanceof ArrayList) {	
			ArrayList<Object> l = ((ArrayList)v.get(0));
			l.remove(0);
			return l;
		}
		else 
			if(v.get(0) instanceof String)	
				return ((String)v.get(0)).substring(1);
			else return null;
	else return null;
	}
	
	
	public static Object saufdernier(ArrayList<Object> v,  HashMap<String, Object> penv) {
		
		if(v.size()== 1)
			if(v.get(0) instanceof ArrayList) {
				ArrayList<Object> l = ((ArrayList)v.get(0));
				l.remove(((ArrayList)v.get(0)).size()-1);
				return l;
			}
			else 
				if(v.get(0) instanceof String)	
					return ((String)v.get(0)).substring(0,((String)v.get(0)).length()-1);
				else return null;
		else return null;
		}
	
	public static Object item(ArrayList<Object> v,  HashMap<String, Object> penv) {
		
		if(v.size()== 2 && v.get(1) instanceof Integer)
			if(v.get(0) instanceof ArrayList)	
				return ((ArrayList)v.get(0)).get((Integer)v.get(1)-1);
			else 
				if(v.get(0) instanceof String)	
					return ((String)v.get(0)).charAt((Integer)v.get(1)-1);
				else return null;
		else return null;
	}
	
	
	public static Object liste(ArrayList<Object> v,  HashMap<String, Object> penv) {
		return v;
	}
	
	
	public static Object phrase(ArrayList<Object> v,  HashMap<String, Object> penv) {
		ArrayList<Object> phrase =new  ArrayList<Object>();
		
		for(int i=0;i<v.size();i++)
			if(v.get(i) instanceof ArrayList)
				phrase.addAll((ArrayList)v.get(i));
			else
				phrase.add(v.get(i));
		
		return phrase;
	}
	
	
	public static Object metspremier(ArrayList<Object> v,  HashMap<String, Object> penv) {
		ArrayList<Object> list =new  ArrayList<Object>();
		
		if(v.size()== 2 && v.get(1) instanceof ArrayList) {
			list.add(v.get(0));
			list.addAll((ArrayList)v.get(1));
			return list;
		}
		else return null;		
	}
	

	public static Object metsdernier(ArrayList<Object> v,  HashMap<String, Object> penv) {
		ArrayList<Object> list =new  ArrayList<Object>();
		
		if(v.size()== 2 && v.get(1) instanceof ArrayList) {
			list.addAll((ArrayList)v.get(1));
			list.add(v.get(0));
			return list;
		}
		else return null;		
	}
	
	
	public static Object inverse(ArrayList<Object> v,  HashMap<String, Object> penv) {
		ArrayList<Object> list =new  ArrayList<Object>();
		ArrayList<Object> v2;
		int t; 
		
		if(v.size()== 1 && v.get(0) instanceof ArrayList) {
			v2 = (ArrayList)v.get(0);
			t= v2.size();
			for(int i=0;i<t;i++)
				list.add(v2.remove(v2.size()-1));
			return list;
		}
		else return null;
	}
	
	
	public static Object compte(ArrayList<Object> v,  HashMap<String, Object> penv) {
		
		
		if(v.size() == 1 ) {
			if(v.get(0) instanceof ArrayList)
				return ((ArrayList)v.get(0)).size();
			if(v.get(0) instanceof String)
				return ((String)v.get(0)).length();
			else return null;
		}
		else return null;
	}
	
}

